package com.xjrsoft.module.system.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.common.annotation.XjrLog;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.handler.FormContentStyleStrategy;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.ExcelUtil;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.system.dto.AddDictionaryDetailDto;
import com.xjrsoft.module.system.dto.DictionaryDetailListDto;
import com.xjrsoft.module.system.dto.DictionaryDetailPageDto;
import com.xjrsoft.module.system.dto.UpdateDictionaryDetailDto;
import com.xjrsoft.module.system.entity.DictionaryDetail;
import com.xjrsoft.module.system.service.IDictionarydetailService;
import com.xjrsoft.module.system.vo.DictionaryDetailExportVo;
import com.xjrsoft.module.system.vo.DictionaryDetailListVo;
import com.xjrsoft.module.system.vo.DictionaryDetailPageVo;
import com.xjrsoft.module.system.vo.DictionaryDetailVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 数据字典详情 前端控制器
 * </p>
 *
 * @author tzx
 * @since 2022-03-17
 */
@RestController
@RequestMapping(GlobalConstant.SYSTEM_MODULE_PREFIX + "/dictionary-detail")
@Api(value = GlobalConstant.SYSTEM_MODULE_PREFIX + "/dictionary-detail",tags = "数据字典详情")
@AllArgsConstructor
public class DictionarydetailController {

    private IDictionarydetailService dictionarydetailService;

    @GetMapping
    @ApiOperation(value = "获取当前数据字典详情（不分页）")
    public R list(DictionaryDetailListDto dto){
        LambdaQueryWrapper<DictionaryDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotEmpty(dto.getName()),DictionaryDetail::getName,dto.getName());
        queryWrapper.like(StrUtil.isNotEmpty(dto.getCode()),DictionaryDetail::getCode,dto.getCode());
        queryWrapper.eq(ObjectUtil.isNotEmpty(dto.getItemId()) && dto.getItemId() != 0,DictionaryDetail::getItemId,dto.getItemId());
        queryWrapper.select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryDetailListVo.class).contains(x.getProperty()));
        queryWrapper.orderByAsc(DictionaryDetail::getSortCode);
        List<DictionaryDetail> list = dictionarydetailService.list(queryWrapper);
        return R.ok(BeanUtil.copyToList(list, DictionaryDetailListVo.class));
    }

    @GetMapping("/page")
    @ApiOperation(value = "获取当前数据字典详情（分页）")
    public R page(DictionaryDetailPageDto dto){
        LambdaQueryWrapper<DictionaryDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotEmpty(dto.getName()),DictionaryDetail::getName,dto.getName())
                    .like(StrUtil.isNotEmpty(dto.getCode()),DictionaryDetail::getCode,dto.getCode())
                    .and(StrUtil.isNotEmpty(dto.getKeyword()), wrapper -> wrapper.like(DictionaryDetail::getName, dto.getKeyword()).or().like(DictionaryDetail::getCode, dto.getKeyword()))
                    .eq(ObjectUtil.isNotEmpty(dto.getItemId()) && dto.getItemId() != 0,DictionaryDetail::getItemId,dto.getItemId())
                    .select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryDetailPageVo.class).contains(x.getProperty()))
                    .orderByAsc(DictionaryDetail::getSortCode);

        IPage<DictionaryDetail> page = dictionarydetailService.page(ConventPage.getPage(dto), queryWrapper);
        PageOutput<DictionaryDetailPageVo> pageOutput = ConventPage.getPageOutput(page, DictionaryDetailPageVo.class);
        return R.ok(pageOutput);
    }

    @GetMapping("/info")
    @ApiOperation(value = "获取当前数据字典详情的详情")
    public R info(@RequestParam Long id){
        DictionaryDetail dictionaryDetail = dictionarydetailService.getById(id);
        if (dictionaryDetail == null) {
            R.error("找不到此字典详情！");
        }
        return R.ok(BeanUtil.toBean(dictionaryDetail, DictionaryDetailVo.class));
    }

    @PostMapping
    @ApiOperation(value = "新增数据字典详情")
    public R add(@Valid @RequestBody AddDictionaryDetailDto dto){

        long count = dictionarydetailService.count(Wrappers.<DictionaryDetail>query().lambda().eq(DictionaryDetail::getItemId, dto.getItemId())
                .and(wrapper -> wrapper.eq(DictionaryDetail::getName, dto.getName())
                        .or().eq(DictionaryDetail::getValue, dto.getValue())
                        .or().eq(DictionaryDetail::getCode, dto.getCode())));
        if(count > 0){
            return R.error("字典名称、编码或值已经存在！");
        }

        DictionaryDetail dictionaryDetail = BeanUtil.toBean(dto, DictionaryDetail.class);

        boolean isSuccess = dictionarydetailService.save(dictionaryDetail);
        if (isSuccess) dictionarydetailService.loadCaches();
        return R.ok(isSuccess);
    }

    @PutMapping
    @ApiOperation(value = "修改数据字典详情")
    public R update(@Valid @RequestBody UpdateDictionaryDetailDto dto){
        long count = dictionarydetailService.count(Wrappers.<DictionaryDetail>query().lambda()
                .eq(DictionaryDetail::getItemId, dto.getItemId())
                .ne(DictionaryDetail::getId,dto.getId())
                .and(wrapper -> wrapper.eq(DictionaryDetail::getName, dto.getName())
                        .or().eq(DictionaryDetail::getValue, dto.getValue())
                        .or().eq(DictionaryDetail::getCode, dto.getCode())));
        if(count > 0){
            return R.error("字典名称、编码或值已经存在！");
        }
        DictionaryDetail dictionaryItem = BeanUtil.toBean(dto, DictionaryDetail.class);

        boolean isSuccess = dictionarydetailService.updateById(dictionaryItem);
        if (isSuccess) dictionarydetailService.loadCaches();
        return R.ok(isSuccess);
    }

    @DeleteMapping
    @ApiOperation(value = "删除数据字典详情")
    public R delete(@RequestBody List<Long> ids){
        return R.ok(dictionarydetailService.removeBatchByIds(ids));
    }

    @PostMapping(value = "/export")
    @ApiOperation(value = "导出")
    @XjrLog(value = "导出表单数据")
    public ResponseEntity<byte[]> export(@Valid @RequestBody Long id) {
        List<DictionaryDetail> list = dictionarydetailService.list(Wrappers.<DictionaryDetail>lambdaQuery().eq(DictionaryDetail::getItemId, id));
        List<DictionaryDetailExportVo> dictionaryDetailExportVos = BeanUtil.copyToList(list, DictionaryDetailExportVo.class);
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot).head(DictionaryDetailExportVo.class).automaticMergeHead(false)
                .registerWriteHandler(new FormContentStyleStrategy())
                .excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dictionaryDetailExportVos);
        ByteArrayOutputStream resultBot = ExcelUtil.renderExportRequiredHead(bot);
        return R.fileStream(resultBot.toByteArray(), "数据字典详情项" + ExcelTypeEnum.XLSX.getValue());
    }

    @GetMapping("/download-template")
    @ApiOperation(value = "下载模板")
    @SneakyThrows
    public ResponseEntity<byte[]> downloadTemplate() {
        List<DictionaryDetailExportVo> databaselinkExportVoList = new ArrayList<>();
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot).head(DictionaryDetailExportVo.class).automaticMergeHead(false)
                .registerWriteHandler(new FormContentStyleStrategy())
                .excelType(ExcelTypeEnum.XLSX).sheet().doWrite(databaselinkExportVoList);
        ByteArrayOutputStream resultBot = ExcelUtil.renderExportRequiredHead(bot);
        return R.fileStream(resultBot.toByteArray(), "数据字典详情项模板" + ExcelTypeEnum.XLSX.getValue());
    }

    @PostMapping("/import")
    @ApiOperation(value = "导入")
    public R importData(@RequestParam MultipartFile file) throws IOException {
        List<DictionaryDetailExportVo> dictionaryItemExportVos = EasyExcel.read(file.getInputStream()).head(DictionaryDetailExportVo.class).sheet().doReadSync();
        List<DictionaryDetail> dictionaryDetails = BeanUtil.copyToList(dictionaryItemExportVos, DictionaryDetail.class);
        //获取所有的字典项
        List<DictionaryDetail> list = dictionarydetailService.list();
        for (DictionaryDetail dictionaryDetail : dictionaryDetails) {
            List<DictionaryDetail> collect = list.stream().filter(x -> x.getItemId().equals(dictionaryDetail.getItemId())).collect(Collectors.toList());
            if (collect.size() > 0){
                List<DictionaryDetail> count = collect.stream().filter(x->x.getName().equals(dictionaryDetail.getName())
                        || x.getCode().equals(dictionaryDetail.getCode()) || x.getValue().equals(dictionaryDetail.getValue())).collect(Collectors.toList());
                if (count.size() > 0){
                    return R.error("导入的字典详情名称、编码或值已经存在！字典详情名称为：" + dictionaryDetail.getName());
                }
            }
        }
        return R.ok(dictionarydetailService.saveBatch(dictionaryDetails));
    }
}
